package douaPahare.algotihm;
import java.util.ArrayList;

import douaPahare.container.Actiune;
import douaPahare.container.Arbore;
import douaPahare.container.Stare;
import douaPahare.operator.Operator;

public class DSFLimited extends Algorithm {
	
	private ArrayList<Stare> listaStariTrecute;
	private ArrayList<Actiune> path;
	private int index;
	private int level;
	
	public DSFLimited(int l) {
		a = Arbore.getInstance();
		a.resetRadacina();
		listaStariTrecute = new ArrayList<Stare>();
		path = new ArrayList<Actiune>();
		solution = false;
		index = 0;
		level = l;
	}
	
	public void solve() {
		System.out.println("---------> Rezolvare folosind algoritmul DSFLimited:");
		int slevel = 0;
		ArrayList<Stare> listaStariAux = new ArrayList<Stare>();
		listaStariAux.add(a.getRadacina());
		while(!isSolution() && slevel <= level) {
			for(Stare s : listaStariAux) { 
				if(!search(s) && !isSolution()) {
					s.setListaStari(expand(s));
					listaStariTrecute.add(s);
					level++;
				}
			}
			listaStariAux.clear();
			for(int i = index;i < listaStariTrecute.size();i++) {
				for(Stare s : listaStariTrecute.get(i).getListaStari()) {
					listaStariAux.add(s);
				}
			}
			index = listaStariTrecute.size();
		} 
		System.out.println("Solution found!");
	}
	
	public ArrayList<Stare> expand(Stare st) {
		System.out.println("Stare : (" + st.getX() + "," + st.getY() + ") expandata : ");
		Stare aux;
		Actiune ac;
		ArrayList<Stare> ls = new ArrayList<Stare>();
		for(Operator op : listaOperatori) {
			if(op.evaluare(st)) {
				aux = op.actiune2(st);
				ac = new Actiune(st,op);
				aux.setParent(ac);
				ls.add(aux);
				aux.printStare();
				if(!search(aux)) {
					path.add(new Actiune(st,op));
					if(aux.getX() == 3 && aux.getY() == 2) {
						solution = true;
						break;
					}
					break;
				}
			} 
		}
		return ls;
	}
	
	public boolean search(Stare st) {
		boolean b = false;
		for(Stare s : listaStariTrecute) {
			if((s.getX() == st.getX()) && (s.getY() == st.getY())) {
				b = true;
				break;
			}
		}
		return b;
	}
	
	public ArrayList<Actiune> getPath() {
		return path;
	}
}
 